package com.tyf.tool;



import java.net.InetAddress;
import java.net.NetworkInterface;
import java.text.SimpleDateFormat;
import java.util.Enumeration;

import org.apache.log4j.HTMLLayout;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.Transform;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

public class Log4jHtmlLayout extends HTMLLayout{
	@Override
	public String getContentType() {
		return "text/html;charset=utf-8";
	}
	public Log4jHtmlLayout() {    
		if(this.serverIp ==null || this.serverIp.length()<=0){
			this.serverIp = this.getLocalIP();
		}
    }     
	
    
	public String serverName = "";
	public String serverIp = "";
	
	static String TRACE_PREFIX = "<br>&nbsp;&nbsp;";     
    
    private StringBuffer sbuf = new StringBuffer(BUF_SIZE);     
         
    String title="PATEO错误日志";     
    
    /**   
     * A string constant used in naming the option for setting the the HTML   
     * document title. Current value of this string constant is <b>Title</b>.   
     */    
    public static final String TITLE_OPTION = "Title";     
    
    // Print no location info by default     
    boolean locationInfo = true;     
         
    public String format(LoggingEvent event) {     
        if (sbuf.capacity() > MAX_CAPACITY) {     
            sbuf = new StringBuffer(BUF_SIZE);     
        } else {     
            sbuf.setLength(0);     
        }     
        sbuf.append(Layout.LINE_SEP + "<tr>" + Layout.LINE_SEP);     
                     
        //时间定义
        sbuf.append("<td>");     
        sbuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));     
        sbuf.append("</td>" + Layout.LINE_SEP);   
        
        sbuf.append("<td>");     
        sbuf.append(serverName);     
        sbuf.append("</td>" + Layout.LINE_SEP);  
        
        sbuf.append("<td>");     
        sbuf.append(serverIp);     
        sbuf.append("</td>" + Layout.LINE_SEP);
    
        //线程
        String escapedThread = Transform.escapeTags(event.getThreadName());
        sbuf.append("<td title=\"" + escapedThread + " thread\">");
        sbuf.append(escapedThread);
        sbuf.append("</td>" + Layout.LINE_SEP);
        
        //级别
        sbuf.append("<td title=\"Level\">");
        if (event.getLevel().equals(Level.DEBUG)) {
          sbuf.append("<font color=\"#339933\">");
          sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
          sbuf.append("</font>");
        }
        else if(event.getLevel().isGreaterOrEqual(Level.WARN)) {
          sbuf.append("<font color=\"#993300\"><strong>");
          sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
          sbuf.append("</strong></font>");
        } else {
          sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
        }
        sbuf.append("</td>" + Layout.LINE_SEP);  
            
        //类名
        String escapedLogger = Transform.escapeTags(event.getLoggerName());
        sbuf.append("<td title=\"" + escapedLogger + " category\">");
        sbuf.append(escapedLogger);
        sbuf.append("</td>" + Layout.LINE_SEP);
        
        //代码错误位置
        if (locationInfo) {     
            LocationInfo locInfo = event.getLocationInformation();     
            sbuf.append("<td title=\"位置\">");    
            sbuf.append(Transform.escapeTags(locInfo.getFileName()));    
            sbuf.append(':');    
            sbuf.append(locInfo.getLineNumber());    
            sbuf.append("</td>" + Layout.LINE_SEP);    
        }    
               
        //消息提醒    
        sbuf.append("<td title=\"消息\">");     
        sbuf.append(Transform.escapeTags(event.getRenderedMessage()));     
        sbuf.append("</td>" + Layout.LINE_SEP);     
        sbuf.append("</tr>" + Layout.LINE_SEP);     
    
        if (event.getNDC() != null) {     
            sbuf.append("<tr><td bgcolor=\"#EEEEEE\" style=\"font-size : xx-small;\" colspan=\"8\" title=\"Nested Diagnostic Context\">");     
            sbuf.append("NDC: " + Transform.escapeTags(event.getNDC()));     
            sbuf.append("</td></tr>" + Layout.LINE_SEP);     
        }     
    
        String[] s = event.getThrowableStrRep();     
        if (s != null) {     
            sbuf.append("<tr><td bgcolor=\"#993300\" style=\"color:White; font-size : xx-small;\" colspan=\"8\">");     
            appendThrowableAsHTML(s, sbuf);     
            sbuf.append("</td></tr>" + Layout.LINE_SEP);     
        }     
        return sbuf.toString();     
    }     
    
    private void appendThrowableAsHTML(String[] s, StringBuffer sbuf) {     
        if (s != null) {     
            int len = s.length;     
            if (len == 0)     
                return;     
            sbuf.append(Transform.escapeTags(s[0]));     
            sbuf.append(Layout.LINE_SEP);     
            for (int i = 1; i < len; i++) {     
                sbuf.append(TRACE_PREFIX);     
                sbuf.append(Transform.escapeTags(s[i]));     
                sbuf.append(Layout.LINE_SEP);     
            }     
        }     
    }     
    
    
    /**   
     * Returns appropriate HTML headers.   
     */    
    public String getHeader() {     
        StringBuffer sbuf = new StringBuffer();     
        sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" + Layout.LINE_SEP);     
        sbuf.append("<html>" + Layout.LINE_SEP);     
        sbuf.append("<head>" + Layout.LINE_SEP);     
      
        sbuf.append("<title>" + title + "</title>" + Layout.LINE_SEP);     
        sbuf.append("<style type=\"text/css\">" + Layout.LINE_SEP);     
        sbuf.append("<!--" + Layout.LINE_SEP);     
        sbuf.append("body, table {font-family: '??',arial,sans-serif; font-size: 12px;}" + Layout.LINE_SEP);     
        sbuf.append("th {background: #336699; color: #FFFFFF; text-align: left;}" + Layout.LINE_SEP);     
        sbuf.append("-->" + Layout.LINE_SEP);     
        sbuf.append("</style>" + Layout.LINE_SEP);     
        sbuf.append("</head>" + Layout.LINE_SEP);     
        sbuf.append("<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">" + Layout.LINE_SEP);     
      
        sbuf.append("<table cellspacing=\"0\" cellpadding=\"4\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">" + Layout.LINE_SEP);     
        sbuf.append("<tr>" + Layout.LINE_SEP);     
         
        sbuf.append("<th>时间</th>" + Layout.LINE_SEP);   
        sbuf.append("<th>应用名称</th>" + Layout.LINE_SEP); 
        sbuf.append("<th>服务器IP</th>" + Layout.LINE_SEP);  
        sbuf.append("<th>线程</th>" + Layout.LINE_SEP);     
        sbuf.append("<th>级别</th>" + Layout.LINE_SEP);     
        sbuf.append("<th>类名</th>" + Layout.LINE_SEP);     
        if (locationInfo) {     
            sbuf.append("<th>代码位置</th>" + Layout.LINE_SEP);     
        }     
        sbuf.append("<th>消息</th>" + Layout.LINE_SEP);     
        sbuf.append("</tr>" + Layout.LINE_SEP);     
        sbuf.append("<br></br>" + Layout.LINE_SEP);     
        return sbuf.toString();     
    }   
    
    
	/**
	 * 获得主机IP
	 * 
	 * @return String
	 */
	public  boolean isWindowsOS() {
		boolean isWindowsOS = false;
		String osName = System.getProperty("os.name");
		if (osName.toLowerCase().indexOf("windows") > -1) {
			isWindowsOS = true;
		}
		return isWindowsOS;
	}

	/**
	 * 获取本机ip地址，并自动区分Windows还是linux操作系统
	 * 
	 * @return String
	 */
	public String getLocalIP() {
		String sIP = "";
		InetAddress ip = null;
		try {
			// 如果是Windows操作系统
			if (isWindowsOS()) {
				ip = InetAddress.getLocalHost();
			}
			// 如果是Linux操作系统
			else {
				boolean bFindIP = false;
				Enumeration<NetworkInterface> netInterfaces = (Enumeration<NetworkInterface>) NetworkInterface
						.getNetworkInterfaces();
				while (netInterfaces.hasMoreElements()) {
					if (bFindIP) {
						break;
					}
					NetworkInterface ni = (NetworkInterface) netInterfaces
							.nextElement();
					// ----------特定情况，可以考虑用ni.getName判断
					// 遍历所有ip
					Enumeration<InetAddress> ips = ni.getInetAddresses();
					while (ips.hasMoreElements()) {
						ip = (InetAddress) ips.nextElement();
						if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() // 127.开头的都是lookback地址
								&& ip.getHostAddress().indexOf(":") == -1) {
							bFindIP = true;
							break;
						}
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (null != ip) {
			sIP = ip.getHostAddress();
		}
		return sIP;
	}
    
    public String getServerName() {
  		return serverName;
  	}
  	public void setServerName(String serverName) {
  		this.serverName = serverName;
  	}
	public String getServerIp() {
		return serverIp;
	}
	public void setServerIp(String serverIp) {
		this.serverIp = serverIp;
	}
}
